import cgi
import re
import datetime
import binascii
import hashlib
import logging
import errors

from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import images
from google.appengine.ext.webapp import template

import appengine_admin
import search
INDEXING_URL = '/tasks/searchindexing'

from xml.etree.ElementTree import parse, fromstring, XML
from django.utils import simplejson as json 

from models import *

salt = '3Eb7k'
logging.getLogger().setLevel(logging.DEBUG)

#method to conv to boolean
def str2bool(v):
    return v.lower() in ("yes", "true", "t", "1")

def input2none(i):
    if i == "None":
	return None
    else:
	return i

def optionalargsjson(obj,field,):
    try:
        return obj[field]
    except:
	return None

def intersect(a, b):
    if not(a):
        return b
    if not(b):
        return a
    else:
        return list(set(a) & set(b))
"""
#tranx method
def updateuserwithlocation(parsed, userid):
        password = parsed.find('password').text  
        savedlocations = parsed.find('savedlocations') #or savedlocation
        location = savedlocations.find('location')  
        # data is collected so create the user entity and location entity
        user = Gauser(  email = parsed.find('email').text,
		    firstname = parsed.find('firstname').text,
		    lastname = parsed.find('lastname').text,
		    currentzip = parsed.find('currentzip').text,
		    gender = parsed.find('gender').text,
		    birthday = datetime.date(1990, 03, 13), #birthday[i].text, convert it to date
		    username = parsed.find('username').text,
		    password = hashlib.sha256(salt + password).hexdigest(),
		    is_public = str2bool(parsed.find('is_public').text),
		    is_calendar_shared = str2bool(parsed.find('is_calendar_shared').text),
        )
	user.email = parsed.find('email').text
	user.firstname = parsed.find('firstname').text
	user.lastname = parsed.find('lastname').text
	user.currentzip = parsed.find('currentzip').text
	user.gender = parsed.find('gender').text
	user.birthday = 
	user.username = parsed.find('username').text
	user.password = hashlib.sha256(salt + password).hexdigest()
	user.is_public = str2bool(parsed.find('is_public').text)
	user.is_calendar_shared = str2bool(parsed.find('is_calendar_shared').text)
	user.date_updated = datetime.datetime.now()
        user.put()
        location = Gauserlocation(  parent = newuser, 
			    	gauser = newuser,
			    	geocode = location.find('geocode').text,
			    	address = location.find('address').text,
			    	city = location.find('city').text,
			    	state = location.find('state').text,
			    	zipcode = location.find('zip').text,
			    	country = location.find('country').text,
			    	is_primary = str2bool(location.find('is_primary').text),
			    	#modified_by =
        )
	
        location.put()    
 """  

"""
helper methods for the registering of user in tranx
 -registeruserwithlocationxml
 -registeruserwithlocationjson

args: accepts input data as xml or json dictionary
"""

def registeruserwithlocationxml(inemail, infirstname, inlastname, incurrentzip, ingender, inbirthday, inusername, inpassword, inis_public, inis_calendar_shared, inis_active, indeviceid, ingeocode, inaddress, incity, instate, inzipcode, incountry, inis_primary, inassociations):
	birthdate = inbirthday
        password1 = inpassword
        newuser = Gauser(  
		    email = str(inemail).lower(),
		    firstname = infirstname,
		    lastname = inlastname,
		    currentzip = input2none(incurrentzip),
		    gender = ingender,
		    birthday = datetime.date(int(birthdate[0:4]) , int(birthdate[5:7]), int(birthdate[8:10]) ),
		    #birthday = datetime.date(int(1990), int( 9), int(5) ),
		    username = (inusername.lower()).replace(' ', ''),
		    #password = hashlib.sha256(salt + password1).hexdigest(),
		    password = password1,
		    is_public = str2bool(inis_public),
		    is_calendar_shared = str2bool(inis_calendar_shared),
		    is_active = str2bool(inis_active),
		    deviceid = input2none(indeviceid),
        )

        newuser.put()
        
        if inaddress != None:
                newlocation = Gauserlocation(  parent = newuser, 
			    	gauser = newuser,
			    	geopoint = input2none(ingeocode),
			    	address = inaddress,
			    	city = incity,
			    	state = instate,
			    	zipcode = inzipcode,
			    	country = incountry,
			    	is_primary = str2bool(inis_primary),
			    	#modified_by =
                )
                newlocation.put()
	if inassociations != None:
	    for association in inassociations:
	        newassociation = Gauserassociation( parent = newuser,
				gauser = newuser,
				associationid = association.findtext('associationid'),
				associationtype= association.findtext('associationtype').lower(),
	        )
	        newassociation.put()
	return newuser.key().id()

def registeruserwithlocationjson(inemail, infirstname, inlastname, incurrentzip, ingender, inbirthday, inusername, inpassword, inis_public, inis_calendar_shared, inis_active, indeviceid, ingeocode, inaddress, incity, instate, inzipcode, incountry, inis_primary, inassociations):
	birthdate = inbirthday
        password1 = inpassword
        newuser = Gauser(  
		    email = str(inemail).lower(),
		    firstname = infirstname,
		    lastname = inlastname,
		    currentzip = input2none(incurrentzip),
		    gender = ingender,
		    birthday = datetime.date(int(birthdate[0:4]) , int(birthdate[5:7]), int(birthdate[8:10]) ),
		    #birthday = datetime.date(int(1990), int( 9), int(5) ),
		    username = (inusername.lower()).replace(' ', ''),
		    #password = hashlib.sha256(salt + password1).hexdigest(),
		    password = password1,
		    is_public = str2bool(inis_public),
		    is_calendar_shared = str2bool(inis_calendar_shared),
		    is_active = str2bool(inis_active),
		    deviceid = input2none(indeviceid),
        )
	    

        newuser.put()
        
        if inaddress != None:
                newlocation = Gauserlocation(  parent = newuser, 
			    	gauser = newuser,
			    	geopoint = input2none(ingeocode),
			    	address = inaddress,
			    	city = incity,
			    	state = instate,
			    	zipcode = inzipcode,
			    	country = incountry,
			    	is_primary = str2bool(inis_primary),
			    	#modified_by =
                )
                newlocation.put()
	if inassociations != None:
	    for association in inassociations:
	        newassociation = Gauserassociation( parent = newuser,
				gauser = newuser,
				associationid = association['associationid'],
				associationtype= association['associationtype'].lower(),
	        )
	        newassociation.put()
	return newuser.key().id()

"""
/rest/(v1|v2)/user/register

register a user with options of saved location (singular) and association (singular)

"""
class UserCreationPage(webapp.RequestHandler):

    def options(self, version):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return

    def delete(self, version):
        header = self.request.headers['Content-Type']

	if "text/xml" in header:
	    parsed = fromstring(self.request.body) 
	    self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    user = Gauser.get_by_id( int (parsed.find('id').text ) )
	    if user != None:
		user.is_active = str2bool('False')
		try: 
		    user.put()
		    self.response.out.write(
"""
<result>%s</result>
</useraccount>""" % user.key().id()
		    )
		except:
		    self.response.out.write(
"""
<result>-1</result>
</useraccount>""" 
		    )  
	    else:
		self.response.out.write(
"""
<result>-2</result>
</useraccount>""" 
		    )  
	    return
   

        elif "application/json" in header:
	    reqobj = json.loads(self.request.body)
	    requser = reqobj['useraccount']
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    user = Gauser.get_by_id( int (requser['id']) )
	
	    if user != None:
	        user.is_active = str2bool('False')
	        try:
	            user.put()
	            useraccount['useraccount']['result'] = user.key().id()
	        except:
	            useraccount['useraccount']['result'] = -1
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write( json.dumps(useraccount) )
	    return
	
	else:
	    return

	    
    def post(self, version):
        header = self.request.headers['Content-Type']
	body = self.request.body
	#need to add something to say if it was successful or failed
	
	#this could be any type of form
        if "multipart/form-data" in header:
	    hashpwd =  hashlib.sha256(salt + str(self.request.get('password')))    
            userbirthday = datetime.date(int(self.request.get('year')), int(self.request.get('month')), int(self.request.get('date')))
	    try:
	        user = Gauser(  email = self.request.get('email'),
			    firstname = self.request.get('firstname'),
			    lastname = self.request.get('lastname'),
			    currentzip = self.request.get('currentzip'),
			    gender = str(self.request.get('gender')),
			    birthday = userbirthday, #birthday[i].text, convert it to dateself.request.get('birthday'),
			    username = self.request.get('username'),
			    #password = hashpwd.hexdigest(),
			    password = self.request.get('password'), 
			    is_public = str2bool(self.request.get('is_public')),
			    is_calendar_shared = str2bool(self.request.get('is_calendar_shared')),
	        )

  	    except ValueError: 
		self.redirect('/home/user')
		return
    	    if self.request.get('image'):
	        user.image = self.request.get('image')        
	
	    user.put()
            self.redirect('/home')
	    return   
	elif "text/xml" in header:
	    requiredkeys = set(['useraccount','email', 'firstname', 'lastname', 'gender', 'birthday', 'username', 'password', 'is_public', 'is_calendar_shared'])
	    locationkeys = set(['location', 'address', 'city', 'state', 'zip', 'country'])
	    associationkeys = set(['association','associationid','associationtype'])
	    keys = set(['useraccount','email', 'firstname', 'lastname', 'currentzip', 'gender', 'birthday', 'username', 'password', 'is_public', 'is_calendar_shared', 'is_active', 'deviceid', 'savedlocations', 'geocode', 'address', 'city', 'state', 'zipcode', 'country', 'is_primary', 'associations', 'associationid','associationtype'])
	    self.response.headers['Content-Type'] = "text/xml"
	    self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>"""
	    )
	    parsed = fromstring(body)
	    xmlkeys = set([a.tag for a in parsed.getiterator()] )
	    if requiredkeys.issubset(xmlkeys):  # checking if it has all required fields
		#if xmlkeys.issubset(keys):	#checking if xml doesn't have any unnecessary fields
		    	email = parsed.findtext('email')
		    	firstname = parsed.findtext('firstname')
		    	lastname = parsed.findtext('lastname')
		    	gender = parsed.findtext('gender')
		    	birthday = parsed.findtext('birthday') 
		    	username = parsed.findtext('username')

		    	password = parsed.findtext('password')
		    	is_public = parsed.findtext('is_public')
		    	is_calendar_shared = parsed.findtext('is_calendar_shared')


		    	savedlocations = parsed.find('savedlocations')
			location = savedlocations.find('location')
			if location != None:
				xmllocationkeys = set([a.tag for a in location.getiterator()])
				if locationkeys.issubset(xmllocationkeys): #check for required location keys
		    			address = location.findtext('address')
		    			city = location.findtext('city')
		    			state = location.findtext('state')
		    			zipcode = location.findtext('zipcode')
		    			country = location.findtext('country')
		    			geocode = location.findtext('geocode')
		    			is_primary = location.findtext('is_primary')
				else:
					#location needs more keys
					neededkeys = locationkeys - xmllocationkeys
					self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (-1, errors.returnerror['field'] % (neededkeys.pop(), 'user location' ) )
	          			)	
	    	    		    	return
	    		deviceid = parsed.findtext('deviceid') 
			currentzip = parsed.findtext('currentzip')
			is_active = parsed.findtext('is_active')
	    		associations = parsed.find('associations') 
			association = associations.findall('association')
	    		if associations != None:
				xmlassociationkeys = set([a.tag for a in associations.getiterator()])
				if associationkeys.issubset(xmlassociationkeys):	
				    for eachassociation in association:
					if eachassociation.findtext('associationtype').lower() not in ['facebook', 'youtube', 'twitter']: 
						self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (-1, errors.returnerror['assoctype'] % eachassociation.findtext('associationtype').lower() )
	          				)	
	    	    		    		return	
				else:
					neededkeys = associationkeys - xmlassociationkeys
		    			self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (-1, errors.returnerror['field'] % (neededkeys.pop(), 'user association' ) )
	          			)
					return
	    		checkusername = db.GqlQuery("SELECT __key__ FROM Gauser WHERE username = :1", ((parsed.find('username').text).lower()).replace(' ', '') )
	    		checkuseremail = db.GqlQuery("SELECT __key__ FROM Gauser WHERE email = :1", (parsed.find('email').text).lower() )
	    		if checkuseremail.count() == 0:
			    if checkusername.count() == 0:
	            		try:
		        		result = db.run_in_transaction(registeruserwithlocationxml, email, firstname, lastname, currentzip, gender, birthday, username, password, is_public, is_calendar_shared, is_active, deviceid, geocode, address, city, state, zipcode, country, is_primary, associations )
            				self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (result, errors.returnerror['created'] % ('user', result) )
	          			)	
				except:
		        		self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (-1, errors.returnerror['transactionfail'])
		        		)
			    else:
				self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (-2, errors.returnerror['exists'] % ('username', username) )
	        		)	
	    		else:
			    self.response.out.write(
"""
<useraccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</useraccount>""" % (-2, errors.returnerror['exists'] % ('email', email) )
	 		    )	
	    else:
		neededkeys = requiredkeys - xmlkeys
	        self.response.out.write(
"""
<businessaccount>
    <result>
	<code>%s</code>
	<message>%s</message>
    </result>
</businessacount>""" % (-1, errors.returnerror['field'] % (neededkeys.pop(), 'user') ) #[a for a in neededkeys] all required keys
	        )
	    return

	elif "application/json" in header:
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    useraccount['useraccount'] = {}

	    reqobj = json.loads(body)
	    """
	    check for required fields	
	    """
	    try:
	    	    requser = reqobj['useraccount']
	    except KeyError, e:
		    useraccount['useraccount']['result'] = {'code':-1, 'message':(errors.returnerror['accountfield'] % e) }
		    self.response.out.write( json.dumps(useraccount) )
	   	    return
	    try:
		    email = requser['email']
		    firstname = requser['firstname'] 
		    lastname = requser['lastname']
		    gender = requser['gender']
		    username = requser['username']
		    birthday = requser['birthday']
        	    password = requser['password']
		    is_public = requser['is_public']
		    is_calendar_shared = requser['is_calendar_shared']
	    except KeyError, e:
		    useraccount['useraccount']['result'] = {'code':-1, 'message':(errors.returnerror['field'] % (e, 'user')) }
		    self.response.out.write( json.dumps(useraccount) )
	    	    return
	    """
	    assigning optional fields or None	
	    """
	    currentzip = optionalargsjson(requser, 'currentzip') 
	    associations = optionalargsjson(requser, 'associations') 
	    is_active = optionalargsjson(requser, 'is_active')
	    deviceid = optionalargsjson(requser, 'deviceid') 
	    """
	    check for associations' fields	
	    """
	    if associations != None:
		for association in associations:
			try:
				associationid = association['associationid']
				associationtype = association['associationtype']
			except KeyError, e:
				useraccount['useraccount']['result'] = {'code':-1, 'message':errors.returnerror['field'] % (e, 'user association' ) }
		    		self.response.out.write( json.dumps(useraccount) )
	    	    		return
			if associationtype.lower() not in ['facebook', 'youtube', 'twitter']: 
		    		    useraccount['useraccount']['result'] = {'code':-1, 'message':errors.returnerror['assoctype'] % associationtype.lower()  }
		    		    self.response.out.write( json.dumps(useraccount) )
	    	    		    return	
	    """
	    check for location's fields	
	    """
	    location = optionalargsjson(requser, 'savedlocations') 

	    if location != None:
		try: 	
	    		address = location['address']
	    		city = location['city']
	    		state = location['state']
	    		zipcode = location['zipcode']
	    		country = location['country']		
		except KeyError, e:
			useraccount['useraccount']['result'] = {'code':-1, 'message':errors.returnerror['field'] % (e, 'user location' ) }
		    	self.response.out.write( json.dumps(useraccount) )
	    	    	return	
		geocode = optionalargsjson(location, 'geocode') 
		is_primary = optionalargsjson(location, 'is_primary') 
	    """
	    check for username and email	
	    """
	    checkusername = db.GqlQuery("SELECT __key__ FROM Gauser WHERE username = :1", (requser['username'].lower()).replace(' ','') )
	    checkuseremail = db.GqlQuery("SELECT __key__ FROM Gauser WHERE email = :1", str(requser['email']).lower() )
	    if checkuseremail.count() == 0:
		if checkusername.count() == 0:
	            try:
	                result = db.run_in_transaction(registeruserwithlocationjson, email, firstname, lastname, currentzip, gender, birthday, username, password, is_public, is_calendar_shared, is_active, deviceid, geocode, address, city, state, zipcode, country, is_primary, associations )
			#result = registeruserwithlocationjson( email, firstname, lastname, currentzip, gender, birthday, username, password, is_public, is_calendar_shared, is_active, deviceid, geocode, address, city, state, zipcode, country, is_primary, associations )
		        useraccount['useraccount']['result'] = {'code':result, 'message':errors.returnerror['created'] % ('user', result) }
	            except:
		        useraccount['useraccount']['result'] = {'code':-1, 'message':errors.returnerror['transactionfail'] }
		else:
		    useraccount['useraccount']['result'] = {'code':-2, 'message':errors.returnerror['exists'] % ('username', username) }
	    else:
		useraccount['useraccount']['result'] =  {'code':-2, 'message':errors.returnerror['exists'] % ('email', email) }

	    self.response.out.write( json.dumps(useraccount) )
	    return
	else:
	    #if not json, xml, or multi-part form data
	    return

"""
/rest/(v1|v2)/user/id/(uid#)

v1: xml, v2:json

retrieve full information for a single user given id

"""
class UserInfo(webapp.RequestHandler):

    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return
    
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
            self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
            if user != None:
                self.response.out.write(
"""
	<id>%s</id>
	<username>%s</username>
	<email>%s</email>
	<firstname>%s</firstname>
	<lastname>%s</lastname>
	<currentzip>%s</currentzip>
	<gender>%s</gender>
	<birthday>%s</birthday>
	<password>%s</password>
	<is_active>%s</is_active>
	<is_public>%s</is_public>
	<is_calendar_shared>%s</is_calendar_shared>
	<deviceid>%s</deviceid>
	<date_updated>%s</date_updated>""" % (user.key().id(), user.username, user.email, user.firstname, user.lastname, user.currentzip, user.gender, user.birthday, user.password, user.is_active, user.is_public, user.is_calendar_shared, user.deviceid, user.date_updated  )
                )
                if user.image:
	            self.response.out.write(
"""
	<image><img src='/img?img_id=%s'></img></image>""" % (user.key() )
	      	    )	      
	        if (user.user_associations).count():
                    self.response.out.write(
"""
	<associations>"""
		    )
                    for association in user.user_associations:	    
                        self.response.out.write(
"""
	    <association>
		<id>%s</id>
		<associationtype>%s</associationtype>
		<associationid>%s</associationid>
	    </association>""" % (association.key().id(), association.associationtype, association.associationid)
                        )

                    self.response.out.write(
"""
	</associations>"""
		    )
	        if (user.user_locations).count():
  	            self.response.out.write(
"""
	<savedlocations>"""
		    )
                    for location in user.user_locations:
	    	        self.response.out.write(
"""
	    <location>
		<id>%s</id>
	        <is_primary>%s</is_primary>
		<geocode>%s</geocode>
		<address>%s</address>
		<city>%s</city>
		<state>%s</state>
		<zip>%s</zip>
		<country>%s</country>
	    </location>""" % (location.key().id(), location.is_primary, location.geopoint, location.address, location.city, location.state, location.zipcode, location.country)
		        )
                    self.response.out.write(
"""
	</savedlocations>"""
		    )
                self.response.out.write(
"""
</useraccount>"""
	        )   
                return

            else:
                self.response.out.write(
"""
</useraccount>"""
	        )
		return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type" 	    
	    useraccount = {}
            if user != None:
                tempuser =  {"id": user.key().id(), 
			     "username": user.username, 
			     "email": user.email, 
			     "firstname": user.firstname, 
			     "lastname": user.lastname, 
			     "currentzip": user.currentzip, 
			     "gender": user.gender, 
			     "birthday": str(user.birthday), 
			     "password": user.password, 
			     "is_active": user.is_active, 
			     "is_public": user.is_public, 
			     "is_calendar_shared": user.is_calendar_shared,
			     "deviceid": user.deviceid, 
			     "date_updated": str(user.date_updated),
			    }

                if user.image:
                  tempuser["image"]=[]
                  tempuser['image'].append("src='/img?img_id=%s'" % user.key())
     
	         
                if (user.user_associations).count():
		    tempuser["associations"]= []
		    for association in user.user_associations:
		        tempassoc = 	{
					"id": association.key().id(),
					"associationtype":association.associationtype,
					"associationid":association.associationid
					}    
                        tempuser["associations"].append(tempassoc)
		
                if (user.user_locations).count():
		    tempuser["savedlocations"] = []
		    for location in user.user_locations:
		        temploc =   	{
					"id": location.key().id(),
					"is_primary":location.is_primary, 
					"geocode": str(location.geopoint),
					"address":location.address, 
					"city":location.city, 
					"state":location.state, 
					"zip":location.zipcode, 
					"country": location.country
				    	}
		        tempuser["savedlocations"].append(temploc)
		useraccount["useraccount"] = tempuser
                self.response.out.write( json.dumps(useraccount) )
                return

            else:
		self.response.out.write( json.dumps({'useraccount':None}  ) )
		return

	else:
	    # will have to enter v1 or v2. nothing else should go through
	    return
"""
/rest/(v1|v2)/user/signin

POST (xml)
checks if login credentials match the ones in database

XML (v1)
if pwd matches
   -returns <useraccount><result>{userid}</result></useraccount>
if pwd does not match
   -returns <useraccount><result>-1</result></useraccount>
if user does not exist
   -returns <useraccount><result>-2</result></useraccount>

JSON(v2)
if pwd matches
   -returns {'user':{'result': (user id) } }
if pwd does not match
   -returns {'user':{'result': -1 } }
if user does not exist
   -returns {'user':{'result': -2} }


notes:	currently is checking pwd as plaintext and not ciphertext
	has to use ssl?
"""

class UserAuthenticate(webapp.RequestHandler):
	def options(self, version):
		self.response.headers['Content-Type'] = "application/json"
		self.response.headers['Access-Control-Allow-Origin'] = "*"
		self.response.headers['Vary'] = "Origin"
		self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
		self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
		return     

	def post(self, version):
		header = self.request.headers['Content-Type']
		body = self.request.body
		if 'text/xml' in header:
			self.response.headers['Content-Type'] = "text/xml"
			self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
			)
			parsed = fromstring(body)
			requsername = ((parsed.find('username').text).lower()).replace(' ','')
			reqpassword = parsed.find('password').text
			#query_str1 = "SELECT * FROM Gauser WHERE username = %s ORDER BY date_created DESC LIMIT 10"
			gauser = Gauser.all().filter('username =', requsername).get()
			if gauser!=None:
				if gauser.password == reqpassword:
					self.response.out.write("""<result>%d</result>""" % gauser.key().id() )
				else:
					self.response.out.write("""<result>-1</result>""")
			else:
				self.response.out.write("""<result>-2</result>""")

			self.response.out.write("</useraccount>")
		elif 'application/json' in header:
			self.response.headers['Content-Type'] = "application/json"
			self.response.headers['Access-Control-Allow-Origin'] = "*"
			self.response.headers['Vary'] = "Origin"
			self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
			self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"
			
	   		useraccount = {}
			useraccount['useraccount'] = {}
			reqobj = json.loads(self.request.body)
			requser = reqobj['useraccount']
			
			requsername = (requser['username'].lower()).replace(' ','')
			reqpassword = requser['password']
			gauser = Gauser.all().filter('username = ', requsername).get()
			if gauser != None:
				if gauser.password == requser['password']:
					useraccount['useraccount']['result'] = gauser.key().id()
				else:
					useraccount['useraccount']['result'] = -1
			else:
				useraccount['useraccount']['result'] = -2
			self.response.out.write( json.dumps(useraccount) )
                	return
		else:
			#not v1 or v2
			return


"""
rest/v1/user/update/id/(uid#)

update a user's profile information, no saved locations or associations

XML (v1)
if user is able to update info
   -returns <result> 0 </result>
if no user
   -returns <result> -1 </result>
notes:
	need to put this into tranx or check if the user actually got put into database
	adding saved locations to this update call is an issue. because there can by many saved locations
    	    - what if a user has 10 savedlocations in the call? have to check each location to see if it is in database already? and then put the ones that have not been in database? not a good idea. too many calls to database. 
	could add all database puts into one try call

"""

class UserUpdate(webapp.RequestHandler):
	#probably don't need the ID since ID is already inside the body of the request
    	def options(self, version, ID):
        	self.response.headers['Content-Type'] = "application/json"
        	self.response.headers['Access-Control-Allow-Origin'] = "*"
        	self.response.headers['Vary'] = "Origin"
        	self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        	self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        	return  
        
	def post(self, version, ID):
	    header = self.request.headers['Content-Type']
	    body = self.request.body
	    #if version == 'v1':  
	    if 'text/xml' in header:
	        self.response.headers['Content-Type'] = "text/xml"
	        self.response.out.write(
"""
<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
		)  
	        # do some xml parsing of user
	        parsed = fromstring(body)
	        requserid = ID
	        reqfirstname = parsed.findtext('firstname')
	        reqlastname = parsed.findtext('lastname')
	        reqemail = parsed.findtext('email')
	        reqgender = parsed.findtext('gender')
	        reqcurrentzip = parsed.findtext('currentzip')
	        requsername = parsed.findtext('username')
	        reqbirthday = parsed.findtext('birthday')
		if reqbirthday != None:
			reqbirthday=datetime.date(int(reqbirthday[0:4]),int(reqbirthday[5:7]), int(reqbirthday[8:10]))
	        reqpassword = parsed.findtext('password')
	        reqis_public = parsed.findtext('is_public')
	        reqis_calendar_shared = parsed.findtext('is_calendar_shared')
	        reqdevice_id = parsed.findtext('deviceid')
	        savedlocations = parsed.find('savedlocations')
	        locations = savedlocations.findall('location')
	        associations = parsed.find('associations')
		assoc = associations.findall('association')

		try:
	        	user = Gauser.get_by_id(int(requserid))  #this or ID
	        except ValueError, e:
			self.response.out.write(
"""
error in getting user ID field cannot be: %s
""" % e
			)
			return
	        if user != None:

		    associationsadded = []
		    locationsadded = []

		    user.email = reqemail or user.email
		    user.firstname = reqfirstname or user.firstname
		    user.lastname = reqlastname or user.lastname
		    user.currentzip = reqcurrentzip or user.currentzip
		    user.gender = reqgender or user.gender
		    user.birthday = reqbirthday or user.birthday
		    user.username = requsername or user.username
		    user.password = reqpassword or user.password
		    user.is_public = str2bool(reqis_public) or user.is_public
		    user.is_calendar_shared = str2bool(reqis_calendar_shared) or user.is_calendar_shared
		    user.deviceid = reqdevice_id or user.deviceid

		    for assoc in associations:
			if assoc.find('id') == None:
		        	newassociation = Gauserassociation( parent = user,
						gauser = user,
						associationid = assoc.find('associationid').text,
						associationtype= assoc.find('associationtype').text.lower(),
	        		)
	        		result = newassociation.put()
				associationsadded.append(result.id())
			else:
				updateassoc = Gauserassociation.get_by_id(int(assoc.findtext('id')), parent=user)
				if updateassoc != None:
					updateassoc.associationid = assoc.find('associationid').text or updateassoc.associationid
					updateassoc.associationtype= assoc.find('associationtype').text.lower()	or updateassoc.associationtype
					result = updateassoc.put()
					associationsadded.append(result.id())
				else:
					#this associationid does not exist
					pass

		    for location in locations:
			if location.find('id') == None:
			        newlocation = Gauserlocation(  parent = user, 
			    			gauser = user,
			    			geopoint = location.find('geocode').text,
			    			address = location.find('address').text,
			    			city = location.find('city').text,
			    			state = location.find('state').text,
			    			zipcode = location.find('zip').text,
			    			country = location.find('country').text,
			    			is_primary = str2bool(location.find('is_primary').text),
			    			#modified_by =
                		)
				# locationstoadd.append(newlocation)
                		result = newlocation.put()
				locationsadded.append(result.id())
			else:
				updateloc = Gauserlocation.get_by_id(int(location.findtext('id')), parent=user)
				if updateloc != None:
						updateloc.geopoint = location.findtext('geocode') or updateloc.geopoint
			    			updateloc.address = location.findtext('address') or updateloc.address
			    			updateloc.city = location.findtext('city') or updateloc.city
			    			updateloc.state = location.findtext('state') or updateloc.state
			    			updateloc.zipcode = location.findtext('zip') or updateloc.zipcode
			    			updateloc.country = location.findtext('country') or updateloc.country
			    			updateloc.is_primary = str2bool(location.findtext('is_primary')) or updateloc.is_primary
						result = updateloc.put()
						locationsadded.append(result.id())
				else:
					#this locationid does not exist
					pass
		
		    user.put()	    			
		    self.response.out.write(
"""
<result>%s</result>
<locations>%s</locations>
<associations>%s</associations>""" % (user.key().id() , str(locationsadded), str(associationsadded) )
		    )
		else:
    		    self.response.out.write(
"""
<result>-2</result>"""
		    )
	        self.response.out.write(
"""
</useraccount>"""
	        )
	        return		

	    elif 'application/json' in header:
	        reqobj = json.loads(self.request.body)
	        self.response.headers['Content-Type'] = "application/json"
	        self.response.headers['Access-Control-Allow-Origin'] = "*"
	        self.response.headers['Vary'] = "Origin"
	        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           

		userkeys = set( ['id', 'firstname', 'lastname', 'email', 'gender', 'currentzip', 'username', 'birthday', 'password', 'is_public', 'is_calendar_shared'  ] )
		useraccount = {}
		useraccount['useraccount'] = {}
	        try:
	    	    requser = reqobj['useraccount']
	        except KeyError, e:
		    useraccount['useraccount']['result'] = {'code':-1, 'message':(errors.returnerror['accountfield'] % e) }
		    self.response.out.write( json.dumps(useraccount) )
	   	    return

	        user = Gauser.get_by_id( int( ID) )
	        if user != None:
			associationsadded = []
			locationsadded = []
			dateofbirth = optionalargsjson(requser, 'birthday')
			user.email = optionalargsjson(requser, 'email') or user.email
			user.firstname = optionalargsjson(requser, 'firstname') or user.firstname
			user.lastname = optionalargsjson(requser, 'lastname') or user.lastname
			user.currentzip = optionalargsjson(requser, 'currentzip') or user.currentzip
			user.gender = optionalargsjson(requser, 'gender') or user.gender
			if dateofbirth != None:
			        dateofbirth = datetime.date(int(dateofbirth[:4]), int(dateofbirth[5:7]), int(dateofbirth[8:])) 
			user.birthday = dateofbirth or user.birthday


			user.username = optionalargsjson(requser, 'username') or user.username
			user.password = optionalargsjson(requser, 'password') or user.password
			user.is_public = str2bool(optionalargsjson(requser, 'is_public')) or user.is_public
			user.is_calendar_shared = str2bool(optionalargsjson(requser, 'is_calendar_shared')) or user.is_calendar_shared
			user.deviceid = optionalargsjson(requser, 'deviceid') or user.deviceid


			"""
			adding saved locations and doing checks
			"""
			savedlocations = optionalargsjson(requser, 'savedlocations')
			if savedlocations != None:
				for location in savedlocations:
				    if optionalargsjson(location, 'id') == None:
					#do a check for location fields
					newlocation = Gauserlocation(  parent = user, 
			    				gauser = user,
			    				geopoint = location['geocode'],
			    				address = location['address'],
			    				city = location['city'],
			    				state = location['state'],
			    				zipcode = location['zipcode'],
			    				country = location['country'],
			    				is_primary = str2bool(location['is_primary']),
			    				#modified_by =
                			)
					# locationstoadd.append(newlocation)
                			result = newlocation.put()
					locationsadded.append(result.id())
				    else:
					updateloc = Gauserlocation.get_by_id(int(location['id']), parent=user)
					if updateloc != None:
						updateloc.geopoint = optionalargsjson(location, 'geocode') or updateloc.geopoint
			    			updateloc.address = optionalargsjson(location,'address') or updateloc.address
			    			updateloc.city = optionalargsjson(location ,'city') or updateloc.city
			    			updateloc.state = optionalargsjson(location,'state') or updateloc.state
			    			updateloc.zipcode = optionalargsjson(location,'zip') or updateloc.zipcode
			    			updateloc.country = optionalargsjson(location,'country') or updateloc.country
			    			updateloc.is_primary = str2bool(optionalargsjson(location,'is_primary')) or updateloc.is_primary
						result = updateloc.put()
						locationsadded.append(result.id())
					else:
					    #this locationid does not exist
			 		    pass
			"""
			adding associations and doing checks
			"""
			associations = optionalargsjson(requser, 'associations')
			if associations != None:
				for association in associations:
				    if optionalargsjson(association, 'id') == None:
					#do a check for associations
					newassociation = Gauserassociation(parent=user,
						gauser = user,
						associationid = association['associationid'],
						associationtype= association['associationtype'].lower()
					)
					result = newassociation.put()
					associationsadded.append(result.id() )
				    else:
					updateassoc = Gauserassociation.get_by_id(int(association['id']), parent=user)
					if updateassoc != None:
						if optionalargsjson(association,'associationid') == None:
						    updateassoc.associationid = updateassoc.associationid
						else:
						    updateassoc.associationid = association['associationid']
						if optionalargsjson(association,'associationtype') == None:
						    updateassoc.associationtype=  updateassoc.associationtype
						else:
						    updateassoc.associationtype=  association['associationid'].lower()
						result = updateassoc.put()
						associationsadded.append(result.id())
				        else:
					    	#this associationid does not exist
						pass
			"""
			putting the user into the database
			"""
			try:
				result = user.put()
				useraccount['useraccount']['result'] = {'code':result.id(), 'message':errors.returnerror['updated'] % ('user', result.id()) }
			except:
		        	useraccount['useraccount']['result'] = {'code':-1, 'message':errors.returnerror['transactionfail'] }
	        else: 
			useraccount['useraccount']['result'] = {'code':-2, 'message':errors.returnerror['noidfound'] % ('user', ID) }
		self.response.out.write( json.dumps(useraccount))
		return		
	    else:
		#not json or xml
		return


"""
rest/(v1|v2)/user/list/ids/(uid#,uid#,uid#,...)

returns full user information for the users given a list of user ids
"""

class UsersListInfo(webapp.RequestHandler):
    def options(self, version, ids):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return  
    def get(self, version, ids):
        stringlistofids = re.split("%2C", ids) #%2C is esc char for ,
	intlistofids = [int(each) for each in stringlistofids]
	#listofids = ids.split('%2C')
	if version == 'v1':
            self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccounts>"""	
	    )
	    if intlistofids:
		users = Gauser.get_by_id(intlistofids)
		for user in users:
		    if user != None:
		        self.response.out.write(
"""
	<useraccount>"""
		        )
	                self.response.out.write(
"""
	    <id>%s</id>
	    <username>%s</username>
	    <email>%s</email>
	    <firstname>%s</firstname>
	    <lastname>%s</lastname>
	    <currentzip>%s</currentzip>
	    <gender>%s</gender>
	    <birthday>%s</birthday>
	    <password>%s</password>
	    <is_active>%s</is_active>
	    <is_public>%s</is_public>
	    <is_calendar_shared>%s</is_calendar_shared>
	    <deviceid>%s</deviceid>
	    <date_updated>%s</date_updated>""" % (user.key().id(), user.username, user.email, user.firstname, user.lastname, user.currentzip, user.gender, user.birthday, user.password, user.is_active, user.is_public, user.is_calendar_shared, user.deviceid, user.date_updated )
                        )	
            
             	        if user.image:
	     	            self.response.out.write(
"""
	    <image><img src='/img?img_id=%s'></img></image>""" % (user.key())
		            )	                 
            
                        if (user.user_associations).count() :
                            self.response.out.write(
"""
            <associations>"""
		            )
                            for association in user.user_associations:	    
                                self.response.out.write(
"""
	        <association>
		    <id>%d</id>
		    <associationtype>%s</associationtype>
		    <associationid>%s</associationid>
	        </association>""" % (association.key().id(), association.associationtype, association.associationid)
            	                 )

                            self.response.out.write(
"""
            </associations>"""
		            )
	                if (user.user_locations).count():
  	                    self.response.out.write(
"""
            <savedlocations>"""
		            )
                            for location in user.user_locations:
	    	                self.response.out.write(
"""
	        <location>
		    <id>%d</id>
	            <is_primary>%s</is_primary>
		    <geocode>%s</geocode>
		    <address>%s</address>
		    <city>%s</city>
		    <state>%s</state>
		    <zip>%s</zip>
		    <country>%s</country>
	        </location>""" % (location.key().id(), location.is_primary, location.geopoint, location.address, location.city, location.state, location.zipcode, location.country)
		                )
                            self.response.out.write(
"""
            </savedlocations>"""
		            )
		        self.response.out.write(
"""
	</useraccount>"""
		        )
            self.response.out.write(
"""
</useraccounts>"""
	    )
	    return

	elif version == 'v2':
 	    self.response.headers['Content-Type'] = "application/json"
 	    self.response.headers['Access-Control-Allow-Origin'] = "*"
 	    self.response.headers['Vary'] = "Origin"
 	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
 	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccounts = {} # {"users":[ {user1 ...}, {user2...}, ... {userx...}]}
	    useraccounts["useraccounts"] = []
            if intlistofids:
		users= Gauser.get_by_id(intlistofids)
		for user in users:
		    if user != None:
                        tempuser = {	
				"id":user.key().id(),
				"username": user.username,
				"email":user.email,
				"firstname": user.firstname,
				"lastname": user.lastname,
				"currentzip": user.currentzip,
				"gender": user.gender,
				"birthday": str(user.birthday),
				"password": user.password,
				"is_active": user.is_active,
				"is_public": user.is_public,
				"is_calendar_shared": user.is_calendar_shared,
				"deviceid": user.deviceid,
				"date_updated": str(user.date_updated),
				    }	
                        if user.image:
                  	    tempuser["image"]=[]
                  	    tempuser['image'].append("src='/img?img_id=%s'" % user.key())
     
		        tempuser["associations"]= []
                        if (user.user_associations).count():
		            for association in user.user_associations:
		                tempassoc = {
					"id": association.key().id(),
					"associationtype":association.associationtype,
					"associationid":association.associationid
				    	    }    
                                tempuser["associations"].append(tempassoc)
		        tempuser["savedlocations"] = []
                        if (user.user_locations).count():
		            for location in user.user_locations:
		                temploc =   {
					"id":location.key().id(),
					"is_primary":location.is_primary, 
					"geocode":str(location.geopoint),
					"address":location.address, 
					"city":location.city, 
					"state":location.state, 
					"zip":location.zipcode, 
					"country": location.country
				            }
		                tempuser["savedlocations"].append(temploc)
		        useraccounts["useraccounts"].append(tempuser)
            self.response.out.write( json.dumps(useraccounts) )
	    return

	else:
	    return

"""
/rest/(v1|v2)/user/list

returns the lite information for all users in database

notes:
mainly for debugging purposes to see the ids and info for each user in db
"""


class UsersList(webapp.RequestHandler):
    def options(self, version):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def get(self, version):
        users= Gauser.all()
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccounts>
"""
	    )
	    for user in users:
	        self.response.out.write(
"""
	    <useraccount>"""
	        )
                self.response.out.write(
"""
		<id>%s</id>
		<username>%s</username>
		<email>%s</email>
		<firstname>%s</firstname>
		<lastname>%s</lastname>
		<is_active>%s</is_active>
		<is_public>%s</is_public>
		<date_updated>%s</date_updated>""" % (user.key().id(), user.username, user.email, user.firstname, user.lastname, user.is_active, user.is_public, user.date_updated )
	        )
	        self.response.out.write(
"""	    
	    </useraccount>"""
	        )     
            self.response.out.write(
"""
</useraccounts>"""
	    )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccounts = {}
	    useraccounts["useraccounts"] = []
	    for user in users:
		tempuser = 	{
				"id": user.key().id(),
				"username": user.username,
				"email": user.email,
				"firstname": user.firstname,
				"lastname": user.lastname,
				"is_active": user.is_active,
				"is_public": user.is_public,
				"date_updated": str(user.date_updated),
				}
		useraccounts["useraccounts"].append(tempuser)
	    self.response.out.write( json.dumps(useraccounts) )
	    return

	else:
	    return

"""
/rest/(v1|v2)/user/lite/id/(uid#)

returns the lite information for a user given user id

JSON (v2):
-if user id is found, returns {'user': {...} }
-if no matching user id, it returns {'user': None}

"""

class UserLiteInfo(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
            self.response.out.write(
"""
	<id>%s</id>
	<username>%s</username>
	<email>%s</email>
	<firstname>%s</firstname>
	<lastname>%s</lastname>
	<is_active>%s</is_active>
	<is_public>%s</is_public>
	<is_calendar_shared>%s</is_calendar_shared>	
	<date_updated>%s</date_updated>""" % (user.key().id(), user.username, user.email, user.firstname, user.lastname, user.is_active, user.is_public, user.is_calendar_shared, user.date_updated )
            )
	
            if user.image:
	        self.response.out.write(
"""
	<image><img src='/img?img_id=%s&amp;size=%s'></img></image>""" % (user.key(), str(200) )
            )	                 
            	
            self.response.out.write(
"""
</useraccount>"""
	    )  
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    if user != None:
	        tempuser = 	{
			"id": user.key().id(),
			"username": user.username,
			"email": user.email,
			"firstname": user.firstname,
			"lastname": user.lastname,
			"is_active": user.is_active,
			"is_public": user.is_public,
			"date_updated": str(user.date_updated),
			   	}
	        useraccount["useraccount"] = tempuser
	        self.response.out.write( json.dumps( useraccount) )
	        return
	    else:
		self.response.out.write( json.dumps( {'useraccount': None} ) )
	        return

	else:
	    return   

"""
/rest/(v1|v2)/user/list/lite/ids/(uid#,uid#,uid#,...)

returns the lite info for user given list of user ids

JSON (v2)
if users are found 
   -returns {'users': [ {user1...}, {user2...}, ... ] }
if no users found
   -returns {'users': [] }
if some users are found
   -returns {'users': [ {...}, {...}, ...]} for valid ids 
   -skips the invalid ids
"""

class UsersListLiteInfo(webapp.RequestHandler):
    def options(self, version, ids):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return    
    def get(self, version, ids):
	#stringofids = ids
        stringlistofids = re.split("%2C", ids) #%2C is esc char for ,
	intlistofids = [int(each) for each in stringlistofids]
	#listofids = ids.split('%2C')
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccounts>"""	
	    )
	    if intlistofids: 
		users= Gauser.get_by_id(intlistofids)
		for user in users:
		    if user != None:
		        self.response.out.write(
"""
	<useraccount>"""
		        )
	                self.response.out.write(
"""
	    <id>%s</id>
	    <email>%s</email>
	    <username>%s</username>
	    <firstname>%s</firstname>
	    <lastname>%s</lastname>
	    <is_active>%s</is_active>
	    <is_public>%s</is_public>
	    <is_calendar_shared>%s</is_calendar_shared>
	    <date_updated>%s</date_updated>""" % (user.key().id(), user.email, user.username, user.firstname, user.lastname, user.is_active, user.is_public, user.is_calendar_shared, user.date_updated )
                        )
             	        if user.image:
	     	            self.response.out.write(
"""
	<image><img src='/img?img_id=%s'></img></image>""" % (user.key())
		            )	                 
            
             	        self.response.out.write(
"""
	</useraccount>"""
		        )
	    self.response.out.write(
"""
</useraccounts>"""
            )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccounts = {} # {"users":[ {user1 ...}, {user2...}, ... {userx...}]}
	    useraccounts["useraccounts"] = []
	    if intlistofids:
		users= Gauser.get_by_id(intlistofids)
		for user in users:
		    if user != None:
		        tempuser = {
				"id": user.key().id(),
				"username": user.username,
				"email": user.email,
				"firstname": user.firstname,
				"lastname": user.lastname,
				"is_active": user.is_active,
				"is_public": user.is_public,
				"date_updated": str(user.date_updated),
				    }  
                        if user.image:
                  	    tempuser["image"]=[]
                  	    tempuser['image'].append("src='/img?img_id=%s'" % user.key())
		        useraccounts["useraccounts"].append(tempuser)
	    self.response.out.write( json.dumps(useraccounts) )
	    return

	else:
	    return
		    
"""
/rest/(v1|v2)/user/savedlocations/id/(uid#)

DELETE (xml, json)
deletes savedlocations for a user given the id 

GET (xml, json)
returns the saved locations for a user given user id

POST (xml, json)
adds a savedlocation for a user given the id either inside xml or in url call

JSON (v2)
if user has savedlocations
   -returns {'user': {'id':uid, 'savedlocations': [{location1}, {location2}, ...]} }
if user not valid
   -returns {'user': None}
if user has no locations
   -returns {'user': {'id': uid, 'savedlocations': [] } }

"""


class UserSavedLocations(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return     
	
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    if user != None:
                self.response.out.write(
"""
	<id>%s</id>""" % user.key().id()
	        )
                if (user.user_locations).count():
	            self.response.out.write(
"""
	    <savedlocations>"""
	    	    )
                    for location in user.user_locations:
		        self.response.out.write(
"""
	        <location>
		    <id>%d</id>
	            <is_primary>%s</is_primary>
		    <geocode>%s</geocode>
		    <address>%s</address>
		    <city>%s</city>
		    <state>%s</state>
		    <zip>%s</zip>
		    <country>%s</country>
		    <date_updated>%s</date_updated>
	        </location>""" % (location.key().id(), location.is_primary, location.geopoint, location.address, location.city, location.state, location.zipcode, location.country, location.date_updated)
        	        )
                    self.response.out.write(
"""
	    </savedlocations>"""
	            )
	    else:
		self.response.out.write(
"""
	<result>-2</result>"""
		)
            self.response.out.write(
"""
</useraccount>"""	
            )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
       
	    useraccount = {}
	    if user != None:
		tempuser = {
			'id': user.key().id(),
			   }
	        tempuser["savedlocations"] = []
                if (user.user_locations).count():
                    for location in user.user_locations:
		        temploc =   {
				"id":location.key().id(),
				"is_primary":location.is_primary, 
				"geocode":str(location.geopoint),
				"address":location.address, 
				"city":location.city, 
				"state":location.state, 
				"zip":location.zipcode, 
				"country": location.country
			 	    }
		        tempuser["savedlocations"].append(temploc)
		useraccount['useraccount'] = tempuser
	        self.response.out.write( json.dumps( useraccount) )
                return
	    else:
	        self.response.out.write( json.dumps( {'useraccount': {'result':-2}}) )
                return	

	else:
	    return
	
    def post(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
	        # do some xml parsing of user
	        parsed = fromstring(body)
		self.response.headers['Content-Type'] = "text/xml"
		self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>""")
	        requserid = parsed.find('id').text
	        savedlocations = parsed.find('savedlocations')
	        locations = savedlocations.findall('location')
	        user = Gauser.get_by_id( int(requserid) )
		if user != None:
		    self.response.out.write(
"""
    <results>"""
		    )
	            for eachlocation in locations:
	                reqis_primary = eachlocation.find('is_primary').text
	                reqgeocode = eachlocation.find('geocode').text
	                reqaddress = eachlocation.find('address').text
	                reqcity = eachlocation.find('city').text
	                reqstate = eachlocation.find('state').text
	                reqzip = eachlocation.find('zip').text
	                reqcountry = eachlocation.find('country').text
	                
			try:    
    		            location = Gauserlocation(  
    		                parent = user,
			    	gauser = user,
				gauserid = user.key().id(),
			    	geopoint = input2none( reqgeocode ),
			    	address = reqaddress,
			    	city = reqcity,
			    	state = reqstate,
			    	zipcode = reqzip,
			    	country = reqcountry,
			    	is_primary = str2bool(reqis_primary),
			    	#modified_by =
			    	#date_updated= 
		            )
	                    locationput = location.put()
		            self.response.out.write(
"""
        <result>%d</result>""" % locationput.id()
	        	    ) 
			except:
		            self.response.out.write(
"""
        <result>-1</result>""" 
	        	    )   
		    self.response.out.write(
"""
    </results>"""
		    )    
		else:
		    self.response.out.write(
"""
        <results>-2</results>"""
	            )	 
	        self.response.out.write(
"""
</useraccount>"""
		)
		return

	elif 'application/json' in header:
	        reqobj = json.loads(body)
		userobj = reqobj['useraccount']
		self.response.headers['Content-Type'] = "application/json"
		self.response.headers['Access-Control-Allow-Origin'] = "*"
		self.response.headers['Vary'] = "Origin"
		self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
		self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
		useraccount = {}
		useraccount['useraccount'] = {}
		useraccount['useraccount']['result'] = []
	        requserid = userobj['id']
	        locations = userobj['savedlocations']
	        user = Gauser.get_by_id( int(requserid) )
		if user != None:
	            for eachlocation in locations:
	                reqis_primary = eachlocation['is_primary']
	                reqgeocode = eachlocation['geocode']
	                reqaddress = eachlocation['address']
	                reqcity = eachlocation['city']
	                reqstate = eachlocation['state']
	                reqzip = eachlocation['zip']
	                reqcountry = eachlocation['country']

	                try:     
    		            location = Gauserlocation(  
    		                parent = user,
			    	gauser = user,
				gauserid = user.key().id(),
			    	geocode = input2none(reqgeocode),
			    	address = reqaddress,
			    	city = reqcity,
			    	state = reqstate,
			    	zipcode = reqzip,
			    	country = reqcountry,
			    	is_primary = str2bool(reqis_primary),
			    	#modified_by =
			    	#date_updated= 
		            )
	                    locationput = location.put()
			    useraccount['useraccount']['result'].append(locationput.id())   
			except:
			    useraccount['useraccount']['result'].append(-1)  
		else:
		    useraccount['useraccount']['result'] = -2
		self.response.out.write(json.dumps(useraccount) )
		return

    	else:
	        return

    def delete(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
	if 'text/xml' in header:
	    parsed = fromstring(body)
	    self.response.headers['Content-Type'] = "text/xml"
	    self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>""")
	    requserid = parsed.find('id').text
	    locationids = parsed.find('savedlocations')
	    ids = locationids.findall('locationid')
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in ids:
		    try:
		        location = Gauserlocation.get_by_id(int(eachid.text), parent=user)
		        location.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid.text )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    </results>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif 'application/json' in header:
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    reqobj = json.loads(body)
	    requser = reqobj['useraccount']
	    requserid = requser['id']
	    ids = requser['savedlocations']
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		for eachid in ids:
	            try:
		        location = Gauserlocation.get_by_id(int(eachid), parent=user)
			location.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return

"""
/rest/v1/user/savedlocations/delete/id/(savedlocationid#)

POST 
delete multiple locations given a list of savedlocation ids
"""	

class UserUpdateLocations(webapp.RequestHandler):
    def options(self, version):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def post(self, version):
	header = self.request.headers['Content-Type']
	if 'text/xml' in header:
	    parsed = fromstring(self.request.body)
	    self.response.out.write("""
<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    requserid = parsed.find('id').text
	    locationid = parsed.find('locationid').text
	    user = Gauser.get_by_id( int(requserid) )
	 
	    if user != None:
		location = Gauserlocation.get_by_id(int(locationid), parent=user)
		if location.gauser.key() == user.key():
	            locations = user.user_locations.filter("is_primary = ", True)
	            for loc in locations:
		        loc.is_primary = False
		        loc.put()
		    if location != None:
		        location.is_primary = True
		        location.put()
		        self.response.out.write(
"""
    <result>%s</result>""" % location.key().id() )
		    else:
		        self.response.out.write(
"""
    <result>-1</result>""")
		else:
		    self.response.out.write(
"""
    <result>-1</result>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>"""
	        )
	    return

	elif 'application/json' in header:
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    reqobj = json.loads(self.request.body)
	    requser = reqobj['useraccount']
	    requserid = requser['id']
	    locationid = requser['locationid']
	    user = Gauser.get_by_id( int(requserid) )
	 
	    if user != None:
		location = Gauserlocation.get_by_id(int(locationid), parent=user)
		if location != None:
	            locations = user.user_locations.filter("is_primary = ", True)
	            for loc in locations:
		        loc.is_primary = False
		        loc.put()
		    if location.gauser.key() == user.key():
		        location.is_primary = True
		        location.put()
			useraccount['useraccount']['result'] = location.key().id()

		    else:
		        useraccount['useraccount']['result'] = -1
		else:
		    useraccount['useraccount']['result'] = -1
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return

	else:
	    return

class UserDeleteLocations(webapp.RequestHandler):
    def options(self, ids):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      

    def delete(self, version, userid, ids):
        stringlistofids = ids.split("%2C")
	intlistofids = [ int(each) for each in stringlistofids]
	if version == 'v1':
	    self.response.out.write("""
<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	)
	    user = Gauser.get_by_id(int(userid))
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in intlistofids:
		    try:
		        location = Gauserlocation.get_by_id(eachid, parent=user)
		        location.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    <results>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    user = Gauser.get_by_id( int(userid) )
	    if user != None:
		for eachid in intlistofids:
	            try:
		        location = Gauserlocation.get_by_id(eachid, parent=user)
			location.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return


#def useraddfriends(listofids):
     

"""
/rest/(v1|v2)/user/friends/id/(uid#)

GET(xml, json)
returns list of all friends' ids for a given user id

JSON (v2)
if user and friends
   -returns {'user': {'id':uid, 'friends':[{friend1}, {friend2},... ] } }
if not valid user
   -returns {'user': None }
if user and no friends
   -returns {'user': {'id':uid, 'friends':[] } }

POST(xml)
adds friends to user given user id and friend ids (multiple)
"""
#friends of users
class UserFriends(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return    
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    if user != None:
                self.response.out.write(
"""
	<id>%s</id>""" % user.key().id()
	        )
                if (user.user_friends).count() :
	            self.response.out.write(
"""
	    <friendships>"""
	            )
                    for buddy in user.user_friends:
		        self.response.out.write(
"""
	        <friend>
		    <useraddedfriendid>%s</useraddedfriendid>
		    <friendid>%s</friendid>
		    <date_updated>%s</date_updated>
		</friend>""" % (buddy.key().id(), buddy.friend.key().id(), buddy.date_updated)
        	        )
                    self.response.out.write(
"""
	    </friendships>"""
	            )
	    else:
		self.response.out.write(
"""
	<result>-2</result>"""
		)
            self.response.out.write(
"""
</useraccount>"""
	    )	
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    if user != None:
		tempuser = 	{
			'id': user.key().id(),
				}
	        tempuser["friendships"] = []
                if (user.user_friends).count():
                    for buddy in user.user_friends:
		        tempbud =   {
				"useraddedfriendid": buddy.key().id(),
				"friendid":buddy.friend.key().id(), 
				"date_updated": str(buddy.date_updated),
			 	}
		        tempuser["friendships"].append(tempbud)
		useraccount['useraccount'] = tempuser
	        self.response.out.write( json.dumps( useraccount) )
                return
	    else:
		self.response.out.write( json.dumps( {'useraccount': None}) )
                return

	else:
	    return

    #this post might need to loop over a bunch of friendid's findall instead of find
    def post(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
                self.response.headers['Content-Type'] = "text/xml"
                self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	        )
	        # do some xml parsing of user
	        parsed = fromstring(body)
	        requserid = parsed.find('id').text
	        friendships = parsed.find('friendships')
	        friends = friendships.findall('friend')
	        user = Gauser.get_by_id( int(requserid) )
		if user!= None:
		    self.response.out.write(
"""
    <results>""")
	            for eachfriend in friends:     
	                friend = Gauser.get_by_id(int (eachfriend.find('friendid').text)) 
		        if friend != None:
			    try:
    		                friendship = Gauserfriend(  
					parent = user,
			     		gauser = user,
			    		friend = friend,
			     		gauserid = user.key().id(),
			    		friendid = friend.key().id(),
			    		status = 0,
			    	#modified_by =
			    	#date_updated= 
		                )
	                        friendship.put()
		                self.response.out.write(
"""
        <result>%s</result>""" % friendship.key().id()
		            )
			    except:
				self.response.out.write(
"""
	<result>-1</result>""")
		        else:
			    self.response.out.write(
"""
	<result>-2</result>""")
		    self.response.out.write(
"""
    </results>""")
		else:
		    self.response.out.write(
"""
    <results>-2</results>""")
		self.response.out.write("""
</useraccount>"""
		)
	        return

    	elif 'application/json' in header:
	        reqobj = json.loads(self.request.body)
	        requser = reqobj['useraccount']

 	        self.response.headers['Content-Type'] = "application/json"
	        useraccount = {}
	        useraccount['useraccount'] = {}
	        useraccount['useraccount']['result'] = []

	        requserid = requser['id']
	        friends = requser['friendships']
	        user = Gauser.get_by_id( int(requserid) ) #or use ID
		if user != None:
	            for eachfriend in friends:
	                friend = Gauser.get_by_id(int (eachfriend['friendid'])) 
			if friend != None:
			    try:
    		                friendship = Gauserfriend(  
    		                   	parent = user,
			    	    	gauser = user,
			    	    	friend = friend,
			     		gauserid = user.key().id(),
			    		friendid = friend.key().id(),
				    	status = 0,
			    	    #modified_by =
			    	    #date_updated= 
		                )
	                        friendship.put()
	                        useraccount['useraccount']['result'].append( friendship.key().id() )
			    except:
	                        useraccount['useraccount']['result'].append(-1)
			else:
	                    useraccount['useraccount']['result'].append(-2)
		else:
		    useraccount['useraccount']['result'] = -2
		self.response.out.write( json.dumps( useraccount ) )
	        return

	else:
	        return

    def delete(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
	if 'text/xml' in header:
	    parsed = fromstring(body)
	    self.response.headers['Content-Type'] = "text/xml"
	    self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>""")
	    requserid = parsed.find('id').text
	    friendids = parsed.find('friendships')
	    ids = friendids.findall('addedfriendid')
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in ids:
		    try:
		        friendship = Gauserfriend.get_by_id(int(eachid.text), parent=user)
		        friendship.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    </results>""")
	    else:
		self.response.out.write(
"""
    <results>-2</results>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif 'application/json' in header:
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    reqobj = json.loads(body)
	    requser = reqobj['useraccount']
	    requserid = requser['id']
	    ids = requser['friendships']
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		for eachid in ids:
	            try:
		        friendship = Gauserfriend.get_by_id(int(eachid), parent=user)
			friendship.delete()
			useraccount['useraccount']['result'].append(eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return

"""
user accept friend
POST: 
1)change the status of received friend to 1 
2)create a new friend-> user row on table status = 1

"""
###class AcceptFriends(webapp.RequestHandler):
###    def post(self, version):
	
	
"""
/rest/v1/user/friends/delete/id/(userfriendid#)

POST 
delete multiple friends given a list of friends ids

issues:  should i send the gauserfriend id or friend's id
	 deleting single user? (uid,)
"""
class UserDeleteFriends(webapp.RequestHandler):
    def options(self, ids):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def delete(self, version, userid, ids):
        stringlistofids = ids.split("%2C")
	intlistofids = [ int(each) for each in stringlistofids]
	if version == 'v1':
	    self.response.out.write("""
<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	)
	    user = Gauser.get_by_id(int(userid))
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in intlistofids:
		    try:
		        userfriend = Gauserfriend.get_by_id(eachid, parent=user)
		        userfriend.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    <results>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    user = Gauser.get_by_id( int(userid) )
	    if user != None:
		for eachid in intlistofids:
	            try:
		        userfriend = Gauserfriend.get_by_id(eachid, parent=user)
			userfriend.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return


"""
/rest/(v1|v2)/user/businesses/id/(uid#)

GET(xml, json)
returns list of all businesses for a given user id

JSON (v2)
if user and fav businesses
   -returns {'user': {'id':uid, 'fav_businesses':[{biz1}, {biz2},... ] } }
if not valid user
   -returns {'user': None }
if user and no fav businesses
   -returns {'user': {'id':uid, 'fav_businesses':[] } }

POST(xml)
adds businesses to user given user id and business ids (multiple)
"""

class UserFavoriteBusinesses(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    if user != None:
                self.response.out.write(
"""
	<id>%s</id>""" % user.key().id()
	        )
                if (user.user_businesses).count():
	            self.response.out.write(
"""
	<fav_businesses>"""
	            )
                    for biz in user.user_businesses:
		        self.response.out.write(
"""	        <business>
		    <useraddedbusinessid>%s</useraddedbusinessid>
		    <businessid>%s</businessid>
		    <date_updated>%s</date_updated>
		</business>""" % (biz.key().id(), biz.gabusiness.key().id(), biz.date_updated)
        	        )
                    self.response.out.write(
"""
	</fav_businesses>"""
	            )
	    else:
		self.response.out.write(
"""
	<result>-2</result>"""
		)
            self.response.out.write(
"""
</useraccount>"""
            )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    if user != None:
		tempuser = 	{
			'id': user.key().id(),
				}
	        tempuser["fav_businesses"] = []
                if (user.user_businesses).count():
                    for biz in user.user_businesses:
		        tempbiz =   {
				"useraddedbusinessid": biz.key().id(),
				"businessid":biz.gabusiness.key().id(), 
				"date_updated": str(biz.date_updated),
			 	    }
		        tempuser["fav_businesses"].append(tempbiz)

		useraccount['useraccount'] = tempuser
	        self.response.out.write( json.dumps( useraccount) )
                return

	    else:
	        self.response.out.write( json.dumps( {'useraccount': None}) )
                return

	else:
	    return

    #this post might need to loop over a bunch of friendid's findall instead of find
    def post(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
                self.response.headers['Content-Type'] = "text/xml"
                self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	        )
	        # do some xml parsing of user
	        parsed = fromstring(body)
	        requserid = parsed.find('id').text
	        fav_businesses = parsed.find('fav_businesses')
	        businesses = fav_businesses.findall('business')
	        user = Gauser.get_by_id( int(requserid) )
		if user != None:
		    userbusinesses = user.user_businesses
		    self.response.out.write(
"""
    <results>""")
	            for business in businesses:
	                biz = Gabusiness.get_by_id(int (business.find('businessid').text)) 
			if biz != None:
			    checkbiz = userbusinesses.filter("gabusiness = ", biz)
			    if checkbiz.count() == 0:
			        try:
    		                    addedbiz = Gauseraddedbusiness(  
    		             		 parent = user,
			    	   	 gauser = user,
			    	   	 gabusiness = biz,
					 gauserid = user.key().id(),
					 gabusinessid = biz.key().id(),			 
			    	    #modified_by =
			    	    #date_updated= 
		                    )
	                            addedbiz.put()
		                    self.response.out.write(
"""
        <result>%s</result>""" % addedbiz.key().id() )
			        except:
				    self.response.out.write(
"""
	<result>-1</result>""")
			    else:
				self.response.out.write(
"""
	<result>0</result>""")
			else:
			    self.response.out.write(
"""
	<result>-2</result>""")
		    self.response.out.write(
"""
    </results>""")
		else:
		    self.response.out.write(
"""
<results>-2</results>""")		    
	        self.response.out.write(
"""
</useraccount>""")
	        return

    	elif 'application/json' in header:
	        reqobj = json.loads(self.request.body)
	        requser = reqobj['useraccount']

 	        self.response.headers['Content-Type'] = "application/json"
	        useraccount = {}
	        useraccount['useraccount'] = {}
	        useraccount['useraccount']['result'] = []

	        requserid = requser['id']
	        businesses = requser['fav_businesses']
	        user = Gauser.get_by_id( int(requserid) ) #or use ID
		if user != None:
		    userbusinesses = user.user_businesses
	            for business in businesses:
	                biz = Gabusiness.get_by_id(int (business['businessid'])) 
			if biz != None:
			    checkbiz = userbusinesses.filter("gabusiness = ", biz)
			    if checkbiz.count() == 0:
			        try:
    		            	    addedbiz = Gauseraddedbusiness(  
    		        		parent = user,
			    		gauser = user,
			    		gabusiness = biz,
					gauserid = user.key().id(),
					gabusinessid = biz.key().id(),	
			    	#modified_by =
			    	#date_updated= 
		            	    )
	                    	    addedbiz.put()
	                    	    useraccount['useraccount']['result'].append( addedbiz.key().id() )
			        except:
			    	    useraccount['useraccount']['result'].append(-1)
			    else:
				useraccount['useraccount']['result'].append(0)
			else:
			    useraccount['useraccount']['result'].append(-2)
		else:
		    useraccount['useraccount']['result'] = -2

		self.response.out.write( json.dumps( useraccount ) )
	        return
	else:
	        return

    def delete(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
	if 'text/xml' in header:
	    parsed = fromstring(body)
	    self.response.headers['Content-Type'] = "text/xml"
	    self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>""")
	    requserid = parsed.find('id').text
	    businessids = parsed.find('fav_businesses')
	    ids = businessids.findall('addedbusinessid')
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in ids:
		    try:
		        business = Gauseraddedbusiness.get_by_id(int(eachid.text), parent=user)
			business.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid.text )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    </results>""")
	    else:
		self.response.out.write(
"""
    <results>-2</results>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif 'application/json' in header:
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    reqobj = json.loads(body)
	    requser = reqobj['useraccount']
	    requserid = requser['id']
	    ids = requser['fav_businesses']
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		for eachid in ids:
	            try:
		        business = Gauseraddedbusiness.get_by_id(int(eachid), parent=user)
			business.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return

"""
/rest/v1/user/businesses/delete/id/(usersavedlocationid#)

POST 
delete multiple businesses given a list of businesses ids

issues:  deleting single biz? (uid,)
"""

class UserDeleteBusinesses(webapp.RequestHandler):
    def options(self, version, ids):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def delete(self, version, userid, ids):
        stringlistofids = ids.split("%2C")
	intlistofids = [ int(each) for each in stringlistofids]
	if version == 'v1':
	    self.response.out.write("""
<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	)
	    user = Gauser.get_by_id(int(userid))
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in intlistofids:
		    try:
		        userbiz = Gauseraddedbusiness.get_by_id(eachid, parent=user)
		        userbiz.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    <results>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    user = Gauser.get_by_id( int(userid) )
	    if user != None:
		for eachid in intlistofids:
	            try:
		        userbiz = Gauseraddedbusiness.get_by_id(eachid, parent=user)
			userbiz.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return

"""
/rest/(v1|v2)/user/events/id/(uid#)

GET(xml, json)
returns list of all events for a given user id

JSON (v2)
if user and events
   -returns {'user': {'id':uid, 'events':[{event1}, {event2},... ] } }
if not valid user
   -returns {'user': None }
if user and no events
   -returns {'user': {'id':uid, 'events':[] } }

POST(xml)
adds events to user given user id and events ids (multiple)
"""
"""
query strings: a daterange... start-> end date... dateview

startdaterequest = self.request.get(u'startdate')

"""
class UserAddedEvents(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return  
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    if user != None:
		events = None
                
		startdate = self.request.get(u'startdate')
		if startdate:
		    events = user.user_events.filter("eventstartdate = ", datetime.date(int(startdate[0:4]), int(startdate[4:6]), int(startdate[6:8]))).order('eventstartdatetime')

		daterange = self.request.get(u'daterange') #YYYYMMDDYYYYMMDD
		if daterange:
		    events = user.user_events.filter("eventstartdate >= ", datetime.date(int(daterange[0:4]), int(daterange[4:6]), int(daterange[6:8])) ).filter("eventstartdate <= ",datetime.date(int(daterange[8:12]), int(daterange[12:14]), int(daterange[14:16])) ).order('eventstartdate').order('eventstartdatetime')

		if not (startdate) and not(daterange):
		    events = user.user_events.order('eventstartdatetime')

                self.response.out.write(
"""
	<id>%s</id>""" % user.key().id()
	        )
                if events.count():
	            self.response.out.write(
"""
	    <events>"""
	            )
                    for event in events:
		            self.response.out.write(
"""	        <event>
		    <useraddedeventid>%s</useraddedeventid>
		    <eventid>%s</eventid>
		    <eventname>%s</eventname>
		    <event_start_date>%s</event_start_date>
		    <event_start_time>%s</event_start_time>
	  	    <is_featured>%s</is_featured>
	    	    <price>%s</price>
	   	    <likecount>%s</likecount>
	   	    <business>%s</business>
		    <status>%s</status>
		    <date_updated>%s</date_updated>""" % (event.key().id(), event.gaevent.key().id(), event.gaevent.eventname, event.eventstartdate, event.eventstarttime, event.gaevent.is_featured, event.gaevent.price, event.gaevent.likecount, event.gaevent.gabusiness.key().id(), event.gaevent.is_active,  event.date_updated)
        	            )
			    self.response.out.write(
"""
	    <categories>
	        <category>"""
	       	 	    )
	        	    if event.gaevent.gacategory.categoryparentname:
		    		self.response.out.write(
"""
		    <maincategory>%s</maincategory>
	            <subcategory>%s</subcategory>""" % (event.gaevent.gacategory.categoryparentname.key().id() , event.gaevent.gacategory.key().id() )
		    		)
			    else:
		    		self.response.out.write(
"""
	            <maincategory>%s</maincategory>""" %  event.gaevent.gacategory.key().id()
		    		)
	        	    self.response.out.write(
"""
	        </category>"""
	        	    )

		            if (event.gaevent.event_categories).count():
	            		for eventcategory in event.gaevent.event_categories:
		        	    self.response.out.write(
"""
	        	<category>""")
		        	    if eventcategory.gacategory.categoryparentname:
	                    		self.response.out.write(
"""
		    	    <maincategory>%s</maincategory>
	            	    <subcategory>%s</subcategory>""" % (eventcategory.gacategory.categoryparentname.key().id() , eventcategory.gacategory.key().id() )
		            		)
		        	    else:
		            		self.response.out.write(
"""
	            	    <maincategory>%s</maincategory>""" %  eventcategory.gacategory.key().id()
		            		)
		        	    self.response.out.write(
"""
	        	</category>""")
			    self.response.out.write(
"""
	    	    </categories>""")
	    #i just put the default thumbnail as the first image, but might need to change it up
		            eventimages = event.gaevent.event_images.get()
		            if eventimages != None:
				mainimage = eventimages.mainimage
		                self.response.out.write(
"""
	<images>"""
		   	 	)
		    	        if eventimages.mainimage == 1:
                        	    self.response.out.write(
"""
	    <image main='%s'><img src='/rest/v1/event/img?img_number=1&amp;img_id=%s'></img></image>""" % (mainimage==1, eventimages.key() )
	      	        	    )
		    	    	elif eventimages.mainimage == 2:
                        	    self.response.out.write(
"""
	    <image main='%s'><img src='/rest/v1/event/img?img_number=2&amp;img_id=%s'></img></image>""" % (mainimage==2,eventimages.key() )
	      	        	    )
		    	   	elif eventimages.mainimage == 3:
                        	    self.response.out.write(
"""
	    <image main='%s'><img src='/rest/v1/event/img?img_number=3&amp;img_id=%s'></img></image>""" % (mainimage==3,eventimages.key() )
	      	        	    )
		    	    	elif eventimages.mainimage == 4:
                        	    self.response.out.write(
"""
	    <image main='%s'><img src='/rest/v1/event/img?img_number=4&amp;img_id=%s'></img></image>""" % (mainimage==4,eventimages.key() )
	      	        	    )
		    	    	else:
		        	    self.response.out.write(
"""
	    <image main='%s'><img src='/rest/v1/event/img?img_number=1&amp;img_id=%s'></img></image>""" % (mainimage==1,eventimages.key() )
	      	        	    )
		                self.response.out.write(
"""
	</images>"""
		    )  
		            self.response.out.write(
"""
	        </event>"""
	                    )
                    self.response.out.write(
"""
	    </events>"""
	            )
	    else:
                self.response.out.write(
"""
    <result>-2</result>"""
	        )
            self.response.out.write(
"""
</useraccount>"""
            )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    if user != None:
		events = None
                

		startdate = self.request.get(u'startdate')
		if startdate:
	            events = db.GqlQuery(	"SELECT * from Gauseraddedevent "+
                                    		"WHERE eventstartdate = :1 " +
						"ORDER BY eventstartdatetime",
                                      		datetime.date(int(startdate[0:4]), int(startdate[4:6]), int(startdate[6:8]) )
		    )
		daterange = self.request.get(u'daterange') #YYYYMMDDYYYYMMDD
		if daterange:
		    events = db.GqlQuery(	"SELECT * from Gauseraddedevent "+
                                    		"WHERE eventstartdate >= :1 AND eventstartdate <= :2 "+
						"ORDER BY eventstartdate, eventstartdatetime",
                                      		datetime.date(int(daterange[0:4]), int(daterange[4:6]), int(daterange[6:8])),
						datetime.date(int(daterange[8:12]), int(daterange[12:14]), int(daterange[14:16])),
		    )
		if events == None:
		    events = user.user_events.order('eventstartdatetime')

		tempuser = 	{
			'id': user.key().id(),
			'eventcount': events.count()
				}
	        tempuser["events"] = []
                if events.count():
                    for event in events:
		        tempevent =   {
				"useraddedeventid": event.key().id(),
				"eventid":event.gaevent.key().id(), 
				"eventname":event.gaevent.eventname,
				"event_start_date":str(event.eventstartdate),
				"event_start_time":str(event.eventstarttime),
				"is_featured":event.gaevent.is_featured, 
				"price":event.gaevent.price, 
				"likecount":event.gaevent.likecount,
				"business": event.gaevent.gabusiness.key().id(),
				"status":event.gaevent.is_active,
				"date_updated": str(event.date_updated),
			 	}
			tempevent['categories'] = []
			tempcategory = {}
			if event.gaevent.gacategory.categoryparentname:
		    	    tempcategory['maincategory'] = event.gaevent.gacategory.categoryparentname.key().id()
		    	    tempcategory['subcategory'] = event.gaevent.gacategory.key().id()
			else:
		    	    tempcategory['maincategory'] = event.gaevent.gacategory.key().id()
			tempevent['categories'].append(tempcategory)

	        	if (event.gaevent.event_categories).count():  
	            	    for eventcategory in event.gaevent.event_categories:
		                tempcategory = {}

		                if eventcategory.gacategory.categoryparentname:
			     	    tempcategory['maincategory'] = eventcategory.gacategory.categoryparentname.key().id()
			    	    tempcategory['subcategory'] = eventcategory.gacategory.key().id()
		                else:
			    	    tempcategory['maincategory'] = eventcategory.gacategory.key().id()
		                tempevent['categories'].append(tempcategory)

		        tempevent['locations'] = []
		        if (event.gaevent.event_locations).count():
                            for eventlocation in event.gaevent.event_locations:
		                temploc = 	{
					'id': eventlocation.key().id(),
					'geocode': str(eventlocation.geopoint),
					'address': eventlocation.address,
					'city': eventlocation.city,
					'state': eventlocation.state,
					'zip': eventlocation.zipcode,
					}
		                tempevent['locations'].append(temploc)

			eventimages = event.gaevent.event_images.get()
	        	if eventimages != None:
			    mainimage = eventimages.mainimage
		    	    tempevent['images'] = []
		   	    if eventimages.mainimage == 1:
				tempimage =	{
						'mainimage': mainimage==1,
						'imagesrc':"src='/rest/v2/event/img?img_number=1&amp;img_id=%s'" % eventimages.key()
						}
                                tempevent['images'].append(tempimage)
		    	    elif eventimages.mainimage == 2:
				tempimage =	{
						'mainimage': mainimage==2,
						'imagesrc':"src='/rest/v2/event/img?img_number=2&amp;img_id=%s'" % eventimages.key()
						}
                        	tempevent['images'].append(tempimage)
		    	    elif eventimages.mainimage == 3:
				tempimage =	{
						'mainimage': mainimage==3,
						'imagesrc':"src='/rest/v2/event/img?img_number=3&amp;img_id=%s'" % eventimages.key()
						}
                        	tempevent['images'].append(tempimage)
		    	    elif eventimages.mainimage == 4:
				tempimage =	{
						'mainimage': mainimage==4,
						'imagesrc':"src='/rest/v2/event/img?img_number=4&amp;img_id=%s'" % eventimages.key()
						}
                        	tempevent['images'].append(tempimage)
		    	    else:
				tempimage =	{
						'mainimage': mainimage==1,
						'imagesrc':"src='/rest/v2/event/img?img_number=1&amp;img_id=%s'" % eventimages.key()
						}
                                tempevent['images'].append(tempimage)


		    	#tempevent['attending'] = []
	            	#if (event.gaevent.events_users).count():
                        #    for eachuser in event.gaevent.events_users:
		        #        tempuser =	{
			#		'id': eachuser.gauser.key().id(),
			#		    	}
		        #        tempevent['attending'].append(tempuser)	
	                tempuser["events"].append(tempevent)


		useraccount['useraccount'] = tempuser
	        self.response.out.write( json.dumps( useraccount) )
                return

	    else:
	        self.response.out.write( json.dumps( {'useraccount': None}) )
                return	

	else:
	    return

    #this post might need to loop over a bunch of friendid's findall instead of find
    def post(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
                self.response.headers['Content-Type'] = "text/xml"
                self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	        )
	        # do some xml parsing of user
	        parsed = fromstring(body)
	        requserid = parsed.find('id').text
	        fav_events = parsed.find('events')
	        events = fav_events.findall('event')
	        user = Gauser.get_by_id( int(requserid) ) #or use ID

		if user != None:
		    userevents = user.user_events
		    self.response.out.write(
"""
    <results>""")
	            for eachevent in events:
	            	event = Gaevent.get_by_id(int (eachevent.find('eventid').text))
			if event != None:
			    eventcheck = userevents.filter("gaevent = ", event)
			    if eventcheck.count() == 0:
			        try:
    		   	   	    addedevent = Gauseraddedevent(  
    		          		parent = user,
			    		gauser = user,
			    		gaevent = event,
			    		gauserid = user.key().id(),
			    		gaeventid = event.key().id(),
					eventstartdatetime = event.eventstartdatetime,
					eventenddatetime = event.eventenddatetime,
					eventstartdate = event.eventstartdate,
					eventenddate = event.eventenddate,
					eventstarttime = event.eventstarttime,
					eventendtime = event.eventendtime,
					eventgeopoint = event.eventgeopoint,
					#eventcategory = event.categories,
			    	#buyticket = ,
			    	#is_public = ,
			    	        is_attending = 0 , 
			    	#is_favorite =  ,			 
			    	#modified_by =
			    	#date_updated= 
		            	    )
	            	    	    addedevent.put()
		    	    	    self.response.out.write(
"""
	<result>%s</result>""" % addedevent.key().id() )
			        except:
				    self.response.out.write(
"""
	<result>-1</result>""")
			    else: #for event repeat
				self.response.out.write(
"""
	<result>0</result>""")
			else:
			    self.response.out.write(
"""
    	<result>-2</result>""" )
		    self.response.out.write(
"""
    </results>""")
		else:
		    self.response.out.write(
"""
    <result>-2</result>""")
		self.response.out.write("""
</useraccount>""")
	        return

    	elif 'application/json' in header:
	        # do some xml parsing of user
	        reqobj = json.loads(self.request.body)
	        requser = reqobj['useraccount']

 	        self.response.headers['Content-Type'] = "application/json"
	        useraccount = {}
	        useraccount['useraccount'] = {}
	        useraccount['useraccount']['result'] = []

	        requserid = requser['id']
	        events = requser['events']
	        user = Gauser.get_by_id( int(requserid) ) #or use ID
		if user != None:
		    userevents = user.user_events
	            for eachevent in events:
	            	event = Gaevent.get_by_id(int (eachevent['eventid']))
			if event != None: 
			    eventcheck = userevents.filter("gaevent = ", event)
			    if eventcheck.count() == 0:
			        try:
    		    	            addedevent = Gauseraddedevent(  
    		            		parent = user,
			    		gauser = user,
			    		gaevent = event,
			    		gauserid = user.key().id(),
			    		gaeventid = event.key().id(),
					eventstartdatetime = event.eventstartdatetime,
					eventenddatetime = event.eventenddatetime,
					eventstartdate = event.eventstartdate,
					eventenddate = event.eventenddate,
					eventstarttime = event.eventstarttime,
					eventendtime = event.eventendtime,
					eventgeopoint = event.eventgeopoint,
			    	#buyticket = ,
			    	#is_public = ,
			    		is_attending = 0 , 
			    	#is_favorite =  ,			 
			    	#modified_by =
			    	#date_updated= 
		                    )
	                            addedevent.put()
	                            useraccount['useraccount']['result'].append( addedevent.key().id() )
			        except:
				    useraccount['useraccount']['result'].append(-1)
			    else: #for event repeat
				useraccount['useraccount']['result'].append(0)
			else:
			    useraccount['useraccount']['result'].append(-2)
		else:
		    useraccount['useraccount']['result']= -2
		self.response.out.write( json.dumps( useraccount ) )
	        return
    	else:
	        return

    def delete(self, version, ID):
    	header = self.request.headers['Content-Type']
        body = self.request.body
	if 'text/xml' in header:
	    parsed = fromstring(body)
	    self.response.headers['Content-Type'] = "text/xml"
	    self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>""")
	    requserid = parsed.find('id').text
	    eventids = parsed.find('events')
	    ids = eventids.findall('eventid')
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in ids:
		    try:
		        event = Gauseraddedevent.get_by_id(int(eachid.text), parent=user)
			event.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid.text )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    </results>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif 'application/json' in header:
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    reqobj = json.loads(body)
	    requser = reqobj['useraccount']
	    requserid = requser['id']
	    ids = requser['events']
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		for eachid in ids:
	            try:
		        event = Gauseraddedevent.get_by_id(int(eachid), parent=user)
			event.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return


"""
/rest/v1/user/events/delete/id/(usereventid#)

POST 
delete multiple events given a list of useraddedevent ids

issues:  deleting single event? (uid,)
"""

class UserDeleteEvents(webapp.RequestHandler):
    def options(self, ids):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return    
    def delete(self, version, userid, ids):
        stringlistofids = ids.split("%2C")
	intlistofids = [ int(each) for each in stringlistofids]
	if version == 'v1':
	    self.response.out.write("""
<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	)
	    user = Gauser.get_by_id(int(userid))
	    if user != None:
		self.response.out.write(
"""
    <results>""")
	        for eachid in intlistofids:
		    try:
		        userevent = Gauseraddedevent.get_by_id(eachid, parent=user)
		        userevent.delete()
		        self.response.out.write(
"""
        <result>%s</result>""" %  eachid )
		    except:
		        self.response.out.write(
"""
	<result>-1</result>""")
		self.response.out.write(
"""
    <results>""")
	    else:
		self.response.out.write(
"""
    <result>-2</result>""")
	    self.response.out.write(
"""
</useraccount>""")
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    useraccount = {}
	    useraccount['useraccount'] = {}
	    useraccount['useraccount']['result'] = []
	    user = Gauser.get_by_id( int(userid) )
	    if user != None:
		for eachid in intlistofids:
	            try:
		        userevent = Gauseraddedevent.get_by_id(eachid, parent=user)
			userevent.delete()
			useraccount['useraccount']['result'].append( eachid)
		    except:
			useraccount['useraccount']['result'].append(-1)
	    else:
		useraccount['useraccount']['result'] = -2
	    self.response.out.write(json.dumps( useraccount))
	    return  
	    
	else:
	    return
"""
/rest/(v1|v2)/user/associations/id/(uid#)

GET(xml, json)
returns list of all associations for a given user id

JSON (v2)
if user and associations
   -returns {'user': {'id':uid, 'associations':[{association1}, {association2},... ] } }
if not valid user
   -returns {'user': None }
if user and no associations
   -returns {'user': {'id':uid, 'associations':[] } }

POST(xml)
adds associations to user given user id and associations ids (multiple)
"""

class UserAssociations(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return    
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
            self.response.out.write(
"""
	<id>%s</id>""" % user.key().id()
	    )
            if (user.user_associations).count():
	        self.response.out.write(
"""
	<associations>"""
	        )
                for assoc in user.user_associations:
		    self.response.out.write(
"""
	        <association>
		   <id>%d</id>
                    <associationid>%s</associationid>
                    <associationtype>%s</associationtype>
	        </association>""" % (assoc.key().id(), assoc.associationid, assoc.associationtype)
        	    )
                self.response.out.write(
"""	    
	</associations>"""
	        )
	    self.response.out.write(
"""
</useraccount>"""	
	    )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    if user != None:
		tempuser = 	{
			'id': user.key().id(),
				}
	        tempuser["associations"] = []
                if (user.user_associations).count():
                    for assoc in user.user_associations:
		        tempassoc = {
				"id": assoc.key().id(),
				"associationid": assoc.associationid,
				"associationtype": str(assoc.associationtype),
			 	    }
		        tempuser["associations"].append(tempassoc)
		useraccount['useraccount'] = tempuser
	        self.response.out.write( json.dumps( useraccount) )
                return
	    else:
	        self.response.out.write( json.dumps( {'useraccount': None}) )
                return

	else:
	    return    


    def post(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
	        # do some xml parsing of user
	        parsed = fromstring(body)
	        requserid = parsed.find('id').text
	        associations = parsed.find('associations')
	        assoc = associations.findall('association')
	        user = Gauser.get_by_id( int(requserid) ) #or use ID
	        for eachassoc in assoc: 
    		    addedassociation = Gauserassociation(  
				parent = user,
			    	gauser = user,
				gauserid = user.key().id(),
			    	associationid = eachassoc.find('associationid').text,
				associationtype = eachassoc.find('associationtype').text,
		        )
	            addedassociation.put()
	        self.redirect('/usercreated?type=%s' % header)
	        return
    	else:
	        self.redirect('/nothingdone?type=%s' % header)
	        return

"""
/rest/(v1|v2)/user/notification/received/id/(uid#)

GET(xml, json)
returns list of all notification for a given user id

JSON (v2)
if user and notifications received
   -returns {'user': {'id':uid, 'notifications':[{notification1}, {notification2},... ] } }
if not valid user
   -returns {'user': None }
if user and no notifications received
   -returns {'user': {'id':uid, 'notifications':[] } }

"""

class UserNotifications(webapp.RequestHandler):
    def options(self, version, ID):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def get(self, version, ID):
        user= Gauser.get_by_id(int(ID))
	if version == 'v1':
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
            self.response.out.write(
"""
	<id>%s</id>""" % user.key().id()
	    )
            if (user.user_receivednotifications).count():
	        self.response.out.write(
"""
	<notifications>"""
	        )
                for notification in user.user_receivednotifications:
		    self.response.out.write(
"""
	        <notification>
                    <sender>%s</sender>
		    <recipient>%s</recipient>
                    <eventid>%s</eventid>
		    <text>%s</text>
		    <is_read>%s</is_read>
		    <date_updated>%s</date_updated>
		    <date_created>%s</date_created>
	        </notification>""" % (notification.notificationby.key().id(), notification.notificationfor.key().id(), notification.event.key().id(), notification.text, notification.is_read, notification.date_updated, notification.date_created)
        	    )
                self.response.out.write(
"""	    
	</notifications>"""
	        )
            self.response.out.write(
"""
</useraccount>"""	
	    )
	    return

	elif version == 'v2':
	    self.response.headers['Content-Type'] = "application/json"
	    self.response.headers['Access-Control-Allow-Origin'] = "*"
	    self.response.headers['Vary'] = "Origin"
	    self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
	    self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
	    useraccount = {}
	    if user != None:
		tempuser = 	{
			'id': user.key().id(),
				}
	        tempuser["notifications"] = []

                if (user.user_receivednotifications).count():
                    for notification in user.user_receivednotifications:
		        tempnotif = {	
				"sender": notification.notificationby.key().id(), 
				"recipient":notification.notificationfor.key().id(),
				"eventid": notification.event.key().id(), 
				"text": notification.text,
				"is_read": notification.is_read,
				"date_updated": str(notification.date_updated),
				"date_created": str(notification.date_created),
			      	    }
		        tempuser['notifications'].append(tempnotif)
	
		useraccount['useraccount'] = tempuser
	        self.response.out.write( json.dumps( useraccount ) )
	        return
	    else:
	        self.response.out.write( json.dumps( {'useraccount':None} ) )
	        return

	else:
	    return

    #the post user is whoever the sender is
    #this seems to have alot of db calls to get the references
    # tranx would be safest method or a different msging system
    """
    def post(self, ID):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
	        # do some xml parsing of user
	        parsed = fromstring(body)
	        requserid = parsed.find('id').text
	        notifications = parsed.find('notifications')
	        notif = associations.findall('notification')
	        user = Gauser.get_by_id( int(requserid) ) #or use ID
	        for eachnotif in notif: 
    		    addednotification = Gausernotification(  
				parent = user,
			    	notificationby = user,
				notificationfor= eachnotif.find('recepient').text,
			    	text = eachnotif.find('text').text,
				event = eachnotif.find('event').text,
		        )
	            addednotification.put()
	        self.redirect('/usercreated?type=%s' % header)
	        return
    	else:
	        self.redirect('/nothingdone?type=%s' % header)
	        return
    """

		
#Image class page
"""
<useraccount>
  <id> USER ID # </id>
  <image> ASCII DATA  </image>
</useraccount>

"""
class UserImagePage (webapp.RequestHandler):
    def options(self, version):
        self.response.headers['Content-Type'] = "application/json"
        self.response.headers['Access-Control-Allow-Origin'] = "*"
        self.response.headers['Vary'] = "Origin"
        self.response.headers['Access-Control-Allow-Methods'] = "OPTIONS, GET, POST, PUT, DELETE"
        self.response.headers['Access-Control-Allow-Headers'] = "Content-Type"           
        return      
    def get(self, version):
        user = db.get(self.request.get("img_id"))
        if user.image:
            self.response.headers['Content-Type'] = "image/jpeg"
            self.response.out.write(user.image)
        else:
            self.response.out.write("No image")  

    def post(self, version):
    	header = self.request.headers['Content-Type']
        body = self.request.body
    	if 'text/xml' in header:
	    self.response.headers['Content-Type'] = "text/xml"
            self.response.out.write(
"""<?xml version="1.0" encoding='utf-8'?>
<useraccount>"""
	    )
	    #do some xml parsing of user
	    parsed = fromstring(body)
	    requserid = parsed.find('id').text
	    user = Gauser.get_by_id( int(requserid) )
	    if user != None:
		imagedata_uni= parsed.find('image').text
		#imagedata_ascii = imagedata_uni.encode('utf8')
	        imagedata_binary = binascii.a2b_base64(imagedata_uni)
		user.image = db.Blob(imagedata_binary)
		try:
		    user.put()
		    self.response.out.write(
"""
<result>0</result>
</useraccount>"""
		    )
		    return
		except:
		    self.response.out.write(
"""<result>-1</result>
</useraccount>"""
		    )
		    return
	    else:
		self.response.out.write(
"""<result>-2</result>
</useraccount>"""
		)
		return	

    	elif 'application/json' in header:
	    self.response.headers['Content-Type'] = "application/json"
            useraccount = {}
	    useraccount['useraccount'] = {} 
	    reqobj = json.loads(self.request.body)
	    requser = reqobj['useraccount']
	    requserid = requser['id']
	    user = Gauser.get_by_id( int(requserid) )

	    if user != None:
		imagedata_uni= requser['image']
		imagedata_binary = binascii.a2b_base64(imagedata_uni)
		user.image = db.Blob(imagedata_binary)
		try:
		    user.put()
	    	    useraccount['useraccount']['result'] = 0 
		    self.response.out.write( json.dumps( useraccount ) )
		    return

		except:
	    	    useraccount['useraccount']['result'] = -1
		    self.response.out.write( json.dumps( useraccount ) )
		    return
	    else:
		useraccount['useraccount']['result'] = -2
		self.response.out.write( json.dumps( useraccount ) )
		return

	else:
	    return
		
		
			


application = webapp.WSGIApplication([
    (r'^/rest/(v1|v2)/user/register$', 					UserCreationPage),
    (r'^/rest/(v1|v2)/user/img/?$',			 		UserImagePage),
    (r'^/rest/(v1|v2)/user/id/(.*)/?$', 				UserInfo ),
    (r'^/rest/(v1|v2)/user/signin/?$', 					UserAuthenticate),
    (r'^/rest/(v1|v2)/user/update/id/(.*)/?$', 				UserUpdate ),
    (r'^/rest/(v1|v2)/user/lite/id/(.*)/?$', 				UserLiteInfo),   
    (r'^/rest/(v1|v2)/user/savedlocations/id/(.*)/deleteids/(.*)/?$', 	UserDeleteLocations),
    (r'^/rest/(v1|v2)/user/savedlocations/id/(.*)/?$', 			UserSavedLocations),
    (r'^/rest/(v1|v2)/user/savedlocations/?$', 				UserSavedLocations),
    (r'^/rest/(v1|v2)/user/savedlocations/updateprimary/?$' ,		UserUpdateLocations),
    (r'^/rest/(v1|v2)/user/friends/id/(.*)/deleteids/(.*)/?$', 		UserDeleteFriends),
    (r'^/rest/(v1|v2)/user/friends/id/(.*)/?$', 			UserFriends),
    (r'^/rest/(v1|v2)/user/friends/?$', 				UserFriends),
    (r'^/rest/(v1|v2)/user/businesses/id/(.*)/deleteids/(.*)/?$', 	UserDeleteBusinesses),
    (r'^/rest/(v1|v2)/user/businesses/id/(.*)/?$', 			UserFavoriteBusinesses),
    (r'^/rest/(v1|v2)/user/businesses/?$', 				UserFavoriteBusinesses),
    (r'^/rest/v1/user/businesses/delete/id/(.*)/?$', 			UserDeleteBusinesses),
    (r'^/rest/(v1|v2)/user/events/id/(.*)/deleteids/(.*)/?$', 		UserDeleteEvents),
    (r'^/rest/(v1|v2)/user/events/id/(.*)/?$', 				UserAddedEvents), #automatically add events from favorite business?
    (r'^/rest/(v1|v2)/user/events/?$', 					UserAddedEvents),
    (r'^/rest/(v1|v2)/user/list/?$', 					UsersList),
    (r'^/rest/(v1|v2)/user/list/ids/(.*)/?$', 				UsersListInfo ),
    (r'^/rest/(v1|v2)/user/list/lite/ids/(.*)/?$', 			UsersListLiteInfo ), 
    (r'^/rest/(v1|v2)/user/associations/id/(.*)/?$', 			UserAssociations ), #add a delete associations later
    (r'^/rest/(v1|v2)/user/notifications/received/id/(.*)/?$', 		UserNotifications ),
], debug=True)
  


def main():
    run_wsgi_app(application)


if __name__ == '__main__':
    main()
